package robotics;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import javax.swing.WindowConstants;

public class ControlarRobot extends JFrame implements Runnable {

    static final long serialVersionUID = 1;
    public static final String nomeRobot = "Guia4";
    private JLabel jAngle;
    private JLabel jRadius;
    private JLabel jDistance;
    private JButton jForward;
    private JButton jReverse;
    private JButton jRight;
    private JButton jLeft;
    private JButton jStop;
    private JLabel jCm2;
    private JLabel jCm1;
    private JLabel jDegrees;
    private JTextField jAngleDegrees;
    private JTextField jRadiusCm;
    private JTextField jDistanceCm;
    public static JTextField jLeftOffset;
    public static JTextField jRightOffset;
    public ActionListener actionListener;
    private JRadioButton jDebug;
    GeometryRobot robot;
    public boolean debug;
    private static final String LEFT_OFFSET_CM = "LeftOffsetCm";
    private static final String RIGHT_OFFSET_CM = "RightOffsetCm";
    // blocking automata
    public static final int DSTRAIGHTFORWARD = 0;
    public static final int DSTRAIGHTREVERSE = 1;
    public static final int DCURVERIGHT = 2;
    public static final int DCURVELEFT = 3;
    public static final int DSTOP = 4;
    public static final int DSTOP_DEPOIS = 5;
    public static final int DNONE = 6;
    private int stateD;
    private int angleDegrees, distanceCm, radiusCm;

    public ControlarRobot() {
//        initRobot();

        stateD = DNONE;
        angleDegrees = 90;
        distanceCm = 19;
        radiusCm = 19;
        debug = false;
        initGUI();
    }

    private void initRobot() {
        robot = new GeometryRobot();

        if (!robot.OpenNXT(nomeRobot)) {
            robot.log("Robot " + nomeRobot + " unsuccessfull find it!");
            System.exit(0);
        } else {
            robot.log("Robot " + nomeRobot + " successfull find it!");
        }
    }

    public void initGUI() {
        setTitle("Robot Remote Control");
        /*
        BufferedImage image = null;
        try {
        image = ImageIO.read(getClass().getClassLoader().getResource("NXT.jpg"));
        } catch (IOException e) {
        e.printStackTrace();
        }
        setIconImage(image);
         */


        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent we) {
                if (robot != null) {
                    robot.CloseNXT();
                }
                System.exit(1);
            }

            public void windowClosed(WindowEvent we) {
                System.exit(0);
            }
        });
        try {
            AnchorLayout thisLayout = new AnchorLayout();
            getContentPane().setLayout(thisLayout);
            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            actionListener = new ActionListener() {

                public void actionPerformed(ActionEvent actionEvent) {
                    robot.log("Action Performed");
                    String command = actionEvent.getActionCommand();
                    robot.log("Selected: " + command);
                    if (command == "Forward") {
                        stateD = DSTRAIGHTFORWARD;
                        return;
                    }
                    if (command == "Reverse") {
                        stateD = DSTRAIGHTREVERSE;
                        return;
                    }
                    if (command == "Left") {
                        stateD = DCURVELEFT;
                        return;
                    }
                    if (command == "Right") {
                        stateD = DCURVERIGHT;
                        return;
                    }
                    if (command == "Stop") {
                        stateD = DSTOP;
                        return;
                    }
                    if (command == "AngleDegrees") {
                        angleDegrees = string2Int(jAngleDegrees.getText(), angleDegrees);
                        jAngleDegrees.setText(Integer.toString(angleDegrees));
                        return;
                    }
                    if (command == "RadiusCm") {
                        radiusCm = string2Int(jRadiusCm.getText(), radiusCm);
                        jRadiusCm.setText(Integer.toString(radiusCm));
                        return;
                    }
                    if (command == "DistanceCm") {
                        distanceCm = string2Int(jDistanceCm.getText(), distanceCm);
                        jDistanceCm.setText(Integer.toString(distanceCm));
                        return;
                    }
                    if (command == "Debug") {
                        robot.setDebug(jDebug.isSelected());
                        return;
                    }
                }
            };
            getContentPane().add(getJDebug(), new AnchorConstraint(917, 191, 994, 14, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJCm2(), new AnchorConstraint(47, 1001, 107, 933, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJCm1(), new AnchorConstraint(47, 626, 107, 563, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJDegrees(), new AnchorConstraint(47, 339, 107, 212, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJForward(), new AnchorConstraint(173, 834, 403, 157, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJStop(), new AnchorConstraint(403, 608, 680, 384, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJReverse(), new AnchorConstraint(680, 834, 914, 157, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJLeft(), new AnchorConstraint(403, 381, 680, 157, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJRight(), new AnchorConstraint(403, 834, 680, 608, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJDistance(), new AnchorConstraint(47, 798, 107, 657, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJDistanceCm(), new AnchorConstraint(35, 930, 119, 798, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJRadius(), new AnchorConstraint(47, 472, 107, 360, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJRadiusCm(), new AnchorConstraint(35, 563, 119, 472, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJAngle(), new AnchorConstraint(47, 125, 107, 29, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJAngleDegrees(), new AnchorConstraint(41, 209, 125, 121, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            // offsets
            getContentPane().add(getJLeftOffsetCm(), new AnchorConstraint(770, 155, 850, 10, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(getJRightOffsetCm(), new AnchorConstraint(770, 1000, 850, 840, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(new JLabel("left offset"), new AnchorConstraint(670, 155, 750, 10, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            getContentPane().add(new JLabel("right offset"), new AnchorConstraint(670, 1000, 750, 840, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
            pack();
            this.setSize(400, 310);
            setVisible(true);
            toFront();
        } catch (Exception e) {
            //add your error handling code here
            e.printStackTrace();
        }
    }

    private int string2Int(String s, int oldNumber) {
        int i;
        try {
            i = Integer.parseInt(s, 10);
        } catch (Exception e) {
            return oldNumber;
        }
        return i;
    }

    private JLabel getJAngle() {
        if (jAngle == null) {
            jAngle = new JLabel();
            jAngle.setText("Angle");
            jAngle.setPreferredSize(new java.awt.Dimension(41, 16));
        }
        return jAngle;
    }

    private JTextField getJAngleDegrees() {
        if (jAngleDegrees == null) {
            jAngleDegrees = new JTextField(3);
            jAngleDegrees.setPreferredSize(new java.awt.Dimension(34, 23));
            jAngleDegrees.setText(Integer.toString(angleDegrees));
            jAngleDegrees.setActionCommand("AngleDegrees");
            jAngleDegrees.addActionListener(actionListener);
        }
        return jAngleDegrees;
    }

    private JLabel getJRadius() {
        if (jRadius == null) {
            jRadius = new JLabel();
            jRadius.setText("Radius");
            jRadius.setPreferredSize(new java.awt.Dimension(43, 16));
        }
        return jRadius;
    }

    private JTextField getJRadiusCm() {
        if (jRadiusCm == null) {
            jRadiusCm = new JTextField(2);
            jRadiusCm.setText(Integer.toString(radiusCm));
            jRadiusCm.setPreferredSize(new java.awt.Dimension(35, 22));
            jRadiusCm.setActionCommand("RadiusCm");
            jRadiusCm.addActionListener(actionListener);
        }
        return jRadiusCm;
    }

    private JLabel getJDistance() {
        if (jDistance == null) {
            jDistance = new JLabel();
            jDistance.setText("Distance");
            jDistance.setPreferredSize(new java.awt.Dimension(54, 16));
        }
        return jDistance;
    }

    private JTextField getJDistanceCm() {
        if (jDistanceCm == null) {
            jDistanceCm = new JTextField(3);
            jDistanceCm.setText(Integer.toString(distanceCm));
            jDistanceCm.setPreferredSize(new java.awt.Dimension(51, 22));
            jDistanceCm.setActionCommand("DistanceCm");
            jDistanceCm.addActionListener(actionListener);
        }
        return jDistanceCm;
    }

    private JTextField getJLeftOffsetCm() {
        if (jLeftOffset == null) {
            jLeftOffset = new JTextField(3);
            jLeftOffset.setText(Integer.toString(0));
            jLeftOffset.setPreferredSize(new java.awt.Dimension(51, 22));
            jLeftOffset.setActionCommand("OffsetLeftCm");
            jLeftOffset.addActionListener(actionListener);
        }
        return jLeftOffset;
    }

    private JTextField getJRightOffsetCm() {
        if (jRightOffset == null) {
            jRightOffset = new JTextField(3);
            jRightOffset.setText(Integer.toString(0));
            jRightOffset.setPreferredSize(new java.awt.Dimension(51, 22));
            jRightOffset.setActionCommand("OffsetRightCm");
            jRightOffset.addActionListener(actionListener);
        }
        return jRightOffset;
    }

    private JButton getJForward() {
        if (jForward == null) {
            jForward = new JButton();
            jForward.setText("FORWARD");
            jForward.setPreferredSize(new java.awt.Dimension(260, 63));
            jForward.setActionCommand("Forward");
            jForward.addActionListener(actionListener);
        }
        return jForward;
    }

    private JButton getJStop() {
        if (jStop == null) {
            jStop = new JButton();
            jStop.setText("STOP");
            jStop.setPreferredSize(new java.awt.Dimension(86, 76));
            jStop.setActionCommand("Stop");
            jStop.addActionListener(actionListener);
        }
        return jStop;
    }

    private JButton getJRight() {
        if (jRight == null) {
            jRight = new JButton();
            jRight.setText("RIGHT");
            jRight.setPreferredSize(new java.awt.Dimension(87, 76));
            jRight.setActionCommand("Right");
            jRight.addActionListener(actionListener);
        }
        return jRight;
    }

    private JButton getJLeft() {
        if (jLeft == null) {
            jLeft = new JButton();
            jLeft.setText("LEFT");
            jLeft.setPreferredSize(new java.awt.Dimension(86, 76));
            jLeft.setActionCommand("Left");
            jLeft.addActionListener(actionListener);
        }
        return jLeft;
    }

    private JButton getJReverse() {
        if (jReverse == null) {
            jReverse = new JButton();
            jReverse.setText("REVERSE");
            jReverse.setPreferredSize(new java.awt.Dimension(260, 64));
            jReverse.setActionCommand("Reverse");
            jReverse.addActionListener(actionListener);
        }
        return jReverse;
    }

    private JLabel getJDegrees() {
        if (jDegrees == null) {
            jDegrees = new JLabel();
            jDegrees.setText("degrees");
            jDegrees.setPreferredSize(new java.awt.Dimension(49, 16));
        }
        return jDegrees;
    }

    private JLabel getJCm1() {
        if (jCm1 == null) {
            jCm1 = new JLabel();
            jCm1.setText("cm");
            jCm1.setPreferredSize(new java.awt.Dimension(24, 16));
        }
        return jCm1;
    }

    private JLabel getJCm2() {
        if (jCm2 == null) {
            jCm2 = new JLabel();
            jCm2.setText("cm");
            jCm2.setPreferredSize(new java.awt.Dimension(26, 16));
        }
        return jCm2;
    }

    private JRadioButton getJDebug() {
        if (jDebug == null) {
            jDebug = new JRadioButton();
            jDebug.setText("Debug");
            jDebug.setPreferredSize(new java.awt.Dimension(68, 21));
            jDebug.setActionCommand("Debug");
            jDebug.addActionListener(actionListener);
        }
        return jDebug;
    }

    public void run() {
        while (true) {
            if (stateD != DNONE) {
                robot.log("stateD: " + stateD);
            }
            switch (stateD) {
                case DSTRAIGHTFORWARD:
                    robot.straight(distanceCm);
                    stateD = DSTOP_DEPOIS;
                    break;
                case DSTRAIGHTREVERSE:
                    robot.straight(-distanceCm);
                    stateD = DSTOP_DEPOIS;
                    break;
                case DCURVERIGHT:
                    robot.curveRight(radiusCm, angleDegrees);
                    stateD = DSTOP_DEPOIS;
                    break;
                case DCURVELEFT:
                    robot.curveLeft(radiusCm, angleDegrees);
                    stateD = DSTOP_DEPOIS;
                    break;
                case DSTOP_DEPOIS:
                    robot.stop(false);
                    stateD = DNONE;
                    break;
                case DSTOP:
                    robot.stop(true);
                    stateD = DNONE;
                    break;
                case DNONE:
//					robot.EsperarMilisegundos(100);
                    break;
            }
        }
    }

    public static void main(String[] args) {
        ControlarRobot inst = new ControlarRobot();
        inst.run();
    }
}
